feat: add web v2 docs and landing updates#197
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Looking for one thing? Review this PR in Change Stack to search files, summaries, diffs, and code without losing your place. Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughLarge docs and marketing refactor: custom DocsLayout/MDX components, icon library migration, content reorganization and redirects, new package-command UX, CSS/theme updates, and new/removed marketing pages. ChangesDocs Platform Refactor and Content Reorg
Sequence Diagram(s)[Skipped] Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (18)
apps/web/src/components/layout/navigation-bar.tsx (5)
51-51: 💤 Low valueRemove unnecessary separator comment.
As per coding guidelines, keep comments rare and avoid separator comments in TypeScript/JavaScript files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/layout/navigation-bar.tsx` at line 51, Remove the unnecessary separator comment line ("// ─── Data ────────────────────────────────────────────────────────────") from the NavigationBar component in apps/web/src/components/layout/navigation-bar.tsx; locate the comment near the top of the file (around where module-level data/constants are defined) and delete that single-line separator so the file follows the project's guideline of avoiding separator comments.Source: Coding guidelines
86-86: 💤 Low valueRemove unnecessary separator comment.
As per coding guidelines, keep comments rare and avoid separator comments in TypeScript/JavaScript files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/layout/navigation-bar.tsx` at line 86, Remove the unnecessary separator comment "// ─── Tab styles ──────────────────────────────────────────────────────" from the NavigationBar component in apps/web/src/components/layout/navigation-bar.tsx; simply delete that standalone comment line (no code changes otherwise) to comply with the guideline of avoiding separator comments in TypeScript/JavaScript files.Source: Coding guidelines
15-15: 💤 Low valueRemove unnecessary separator comment.
As per coding guidelines, keep comments rare and avoid separator comments in TypeScript/JavaScript files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/layout/navigation-bar.tsx` at line 15, Remove the unnecessary separator comment line "// ─── Shared nav link ─────────────────────────────────────────────────" from the navigation-bar component; locate the comment above the shared nav link code (around the SharedNavLink / NavLink related JSX or function) and delete the separator so only meaningful comments or code remain, following the project's guideline to avoid decorative separator comments.Source: Coding guidelines
96-96: 💤 Low valueRemove unnecessary separator comment.
As per coding guidelines, keep comments rare and avoid separator comments in TypeScript/JavaScript files.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/layout/navigation-bar.tsx` at line 96, Remove the unnecessary separator comment line ("// ─── Component ───────────────────────────────────────────────────────") from the NavigationBar component file; locate it in the navigation-bar.tsx near the component declaration and delete that single comment so the file follows the guideline of avoiding visual separator comments.Source: Coding guidelines
98-98: ⚡ Quick winUnused stars parameter and hardcoded value.
The
starsparameter is passed asnulland never used, while the GitHub button displays a hardcoded "1k" value. Either:
- Remove the unused parameter if star count display is not needed
- Use the actual
starsvalue when it's available♻️ Suggested implementation
-export function NavigationBar({ stars: _stars }: { stars: number | null }) { +export function NavigationBar({ stars }: { stars: number | null }) { // ... rest of component <Button render={<Link href={URLs.githubRepo} target="_blank" rel="noopener noreferrer" />} nativeButton={false} variant="ghost" size="sm" className="px-2 -mr-2" > <Icons.GitHubIcon className="size-4.5" /> - <span className="font-sans text-sm">1k</span> + {stars !== null && ( + <span className="font-sans text-sm"> + {stars >= 1000 ? `${(stars / 1000).toFixed(1)}k` : stars} + </span> + )} </Button>Also applies to: 248-249
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/layout/navigation-bar.tsx` at line 98, The NavigationBar component currently accepts an unused parameter named _stars and renders a hardcoded "1k"; either remove the unused prop or surface and use the actual value: change the parameter from { stars: _stars } to { stars } (or remove it altogether) in the NavigationBar function, replace the hardcoded "1k" in the GitHub button render with a dynamic display like stars ?? "1k" (or remove the stars display if you choose to drop the prop), and update any callers that pass null to NavigationBar to either stop passing the prop or pass the real star count; also apply the same fix to the other duplicate instance(s) of the NavigationBar prop usage.apps/web/src/styles/globals.css (2)
286-288: 💤 Low valueAddress stylelint warning.
There should be an empty line before the
max-widthdeclaration per stylelint rules.🔧 Suggested fix
html { `@apply` overflow-x-hidden overflow-y-scroll; + max-width: 100vw; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/styles/globals.css` around lines 286 - 288, There is a stylelint warning because there is no blank line between the `@apply` rule and the subsequent declaration; update the block containing the declarations "`@apply` overflow-x-hidden overflow-y-scroll;" and "max-width: 100vw;" by inserting a single empty line before the "max-width: 100vw;" declaration so the `@apply` and the following property are separated per stylelint rules.Source: Linters/SAST tools
96-96: 💤 Low valueInconsistent color format.
Line 96 uses a hex color (
#f5f5f5) while the rest of the theme usesoklch()format. For consistency, consider converting this to oklch as well.♻️ Suggested fix
- --secondary: `#f5f5f5`; + --secondary: oklch(0.97 0 0);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/styles/globals.css` at line 96, The CSS custom property --secondary currently uses a hex value (`#f5f5f5`) which is inconsistent with the rest of the theme that uses oklch(); update the --secondary declaration in globals.css to an equivalent oklch(...) color so it matches the site's color space and tone (convert the hex to oklch and replace the value for --secondary).apps/web/src/components/docs/docs-code-surface.tsx (1)
5-16: ⚡ Quick winAdd JSDoc to document the component's purpose.
This is an exported, user-facing component used throughout the docs rendering system. Based on coding guidelines, JSDoc should be added to document its purpose, parameters, and the default
tabIndexbehavior.📝 Suggested JSDoc
+/** + * Wrapper for code blocks in documentation pages. + * Provides consistent styling and ensures keyboard accessibility by defaulting tabIndex to 0. + */ export function DocsCodeSurface({ className, tabIndex, ...props }: ComponentProps<"pre">) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/docs-code-surface.tsx` around lines 5 - 16, Add a JSDoc block above the exported DocsCodeSurface function that documents the component's purpose (renders a styled <pre> wrapper for code blocks in the docs system), lists its props (including className, tabIndex, and other ComponentProps<"pre"> passed via ...props), and explicitly states the default tabIndex behavior (defaults to 0 when tabIndex is undefined). Mention any accessibility notes (keyboard focusability due to tabIndex) and the fact that it spreads remaining pre props onto the element; reference the DocsCodeSurface function name so the comment is colocated with the implementation.Source: Learnings
apps/web/src/components/docs/package-manager-state.ts (1)
1-21: ⚡ Quick winAdd JSDoc to document the public API.
All exported entities (
PackageManager, constants, and functions) form the public API for package manager state management. Based on coding guidelines, these should have JSDoc documentation.📝 Suggested JSDoc
+/** Supported package managers for command rendering. */ export type PackageManager = "npm" | "yarn" | "bun" | "pnpm"; +/** List of all supported package managers in display order. */ export const packageManagers = [ "pnpm", "npm", "bun", "yarn", ] as const satisfies readonly PackageManager[]; +/** Local storage key for persisting package manager preference. */ export const packageManagerStorageKey = "paykit-package-manager"; + +/** Default package manager when no preference is stored. */ export const fallbackPackageManager: PackageManager = "pnpm"; +/** + * Type guard to check if a value is a valid PackageManager. + */ export function isPackageManager(value: string | null): value is PackageManager { return packageManagers.includes(value as PackageManager); } +/** + * Parses and validates a package manager value, falling back to the default if invalid. + */ export function parsePackageManager(value: string | null | undefined): PackageManager {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/package-manager-state.ts` around lines 1 - 21, Add JSDoc comments to document the module's public API: describe the exported PackageManager type (allowed values), the packageManagers array (list of supported managers), packageManagerStorageKey (purpose/key used in storage), and fallbackPackageManager (default). For functions isPackageManager(value) and parsePackageManager(value) add JSDoc describing parameters and return types/guards (e.g., `@param` value - input string|null/undefined; `@returns` boolean for isPackageManager and PackageManager for parsePackageManager), and a short usage example or note about behavior (parse returns fallback when invalid). Place comments immediately above each exported symbol (PackageManager, packageManagers, packageManagerStorageKey, fallbackPackageManager, isPackageManager, parsePackageManager).Source: Learnings
apps/web/src/components/docs/package-command-pre.tsx (1)
60-85: ⚡ Quick winAdd JSDoc to document the component's behavior.
This exported async component has complex behavior (parsing, highlighting, conditional rendering) that would benefit from JSDoc documentation per coding guidelines.
📝 Suggested JSDoc
+/** + * Server component that intercepts code blocks to render package manager-specific commands. + * Parses single-line npm commands and renders them as interactive tabs for all package managers. + * Falls back to default rendering for non-matching content. + */ export async function PackageCommandPre( props: ComponentProps<"pre"> & { "data-language"?: string }, ) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/package-command-pre.tsx` around lines 60 - 85, Add a JSDoc block to the exported async component PackageCommandPre describing its behavior and purpose: explain that it normalizes and parses text via normalizeCommand and extractText, conditionally parses with parsePackageCommand, checks language with isShellLanguage, generates highlighted entries by mapping packageManagers and calling highlightShellCommand and commandForManager, and renders either PackageManagerCommandBlock with highlightedCommands or DefaultPre; include param description for props (ComponentProps<"pre"> & { "data-language"?: string }), the return type (JSX.Element | Promise<JSX.Element>), and note that it performs async highlighting side-effects.Source: Learnings
apps/web/src/components/docs/package-command-utils.ts (1)
5-24: ⚡ Quick winAdd JSDoc to document the public API.
The exported
PackageCommandinterface andcommandForManagerfunction form a public API used by other components. Based on coding guidelines, these should have JSDoc documentation explaining their purpose and behavior.📝 Suggested JSDoc
+/** + * Represents a package manager command with its kind and arguments. + */ export interface PackageCommand { kind: CommandKind; args: string; } +/** + * Converts a PackageCommand into the appropriate shell command string for the specified package manager. + * `@param` command - The command to convert + * `@param` manager - The target package manager (npm, yarn, bun, or pnpm) + * `@returns` The formatted shell command string + */ export function commandForManager(command: PackageCommand, manager: PackageManager): string {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/package-command-utils.ts` around lines 5 - 24, Add JSDoc comments for the exported PackageCommand interface and the commandForManager function: document PackageCommand purpose and fields (kind: CommandKind and args: string), and for commandForManager describe purpose, parameters (command: PackageCommand, manager: PackageManager), behavior for each CommandKind branch (how npm/yarn/pnpm/bun are mapped), and the return value (string command). Ensure the JSDoc is placed immediately above the exported declarations and mentions any edge cases (e.g., defaulting to pnpm for dlx) so consumers understand the public API.Source: Learnings
apps/web/src/components/docs/package-command.tsx (2)
35-50: 💤 Low valueConsider whether dual storage persistence is necessary.
The code writes package manager preference to both
sessionStorageandlocalStorage, then reads from both. SincesessionStorageis tab-specific andlocalStorageis global, and you have a pub/sub pattern for cross-instance sync, this dual-write pattern seems redundant.Consider using only
localStoragefor persistent cross-tab preference, or clarify the intent if there's a specific reason for maintaining both.♻️ Potential simplification
function readStoredManager(): PackageManager | null { - const storedValue = - sessionStorage.getItem(packageManagerStorageKey) ?? - localStorage.getItem(packageManagerStorageKey); + const storedValue = localStorage.getItem(packageManagerStorageKey); return isPackageManager(storedValue) ? storedValue : null; } function setStoredManager(value: PackageManager) { - sessionStorage.setItem(packageManagerStorageKey, value); localStorage.setItem(packageManagerStorageKey, value); for (const listener of packageManagerListeners) { listener(value); } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/package-command.tsx` around lines 35 - 50, The code currently persists package manager selections to both sessionStorage and localStorage in setStoredManager and reads from both in readStoredManager; decide on a single storage medium (prefer localStorage for cross-tab persistence) and simplify by writing only to localStorage and reading only from localStorage using packageManagerStorageKey, leaving packageManagerListeners and isPackageManager logic unchanged; if session-scoped behavior is required, document the intent or add a separate explicit function, otherwise remove sessionStorage calls to avoid redundant writes and confusing read fallback behavior.
176-182: ⚡ Quick winExtract duplicated
extractTextutility.The
extractTextfunction is duplicated in bothpackage-command.tsx(lines 176-182) andpackage-command-pre.tsx(lines 11-17). Extract this to a shared utility module to follow DRY principles.♻️ Suggested refactor
Create
apps/web/src/components/docs/utils.ts:import type { ReactNode } from "react"; import { isValidElement } from "react"; /** * Recursively extracts text content from React nodes. */ export function extractText(node: ReactNode): string { if (node === null || node === undefined || typeof node === "boolean") return ""; if (typeof node === "string" || typeof node === "number") return String(node); if (Array.isArray(node)) return node.map(extractText).join(""); if (isValidElement<{ children?: ReactNode }>(node)) return extractText(node.props.children); return ""; }Then import from both files:
+import { extractText } from "`@/components/docs/utils`"; - -function extractText(node: ReactNode): string { - // ... (remove duplicate implementation) -}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/package-command.tsx` around lines 176 - 182, Extract the duplicated extractText function into a single shared utility: create a new utils module that exports extractText, import isValidElement from "react" and keep the same implementation/typing, then replace the local copies in the package-command and package-command-pre components with an import from the new utility and delete the duplicate definitions.apps/web/src/components/docs/mdx-tabs.tsx (2)
32-68: ⚡ Quick winConsider adding JSDoc to exported components.
These components form a user-facing MDX API and would benefit from brief JSDoc describing their purpose and key props. As per coding guidelines, JSDoc should be added on most functions in the library core and on APIs used in many places or user-facing.
📝 Example JSDoc additions
/** * Root tabs component for MDX documentation. * Supports controlled tab selection with optional items array. */ export function MdxTabs({ ... }: MdxTabsProps) { // ... } /** * Tab list container with animated indicator. */ export function MdxTabsList({ ... }) { // ... } /** * Individual tab trigger button. */ export function MdxTabsTab({ ... }) { // ... } /** * Tab content panel. */ export function MdxTabsPanel({ ... }) { // ... } /** * Convenience wrapper that resolves tab value from context. * `@throws` {Error} If no tab value can be resolved from props or context. */ export function MdxTab({ ... }) { // ... }Also applies to: 70-100, 102-116, 118-129, 131-140
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/mdx-tabs.tsx` around lines 32 - 68, Add concise JSDoc comments to each exported MDX tabs component to document their purpose and key props: add a brief description above MdxTabs explaining it's the root tabs component and noting controlled selection props (items, defaultIndex/defaultValue, label), add a short comment above MdxTabsList describing it as the tab list container with indicator, above MdxTabsTab describing it as the individual tab trigger and key props (value, children), above MdxTabsPanel describing it as the content panel, and above MdxTab describing it as a convenience wrapper that resolves value from props or context and include a `@throws` note stating it throws if no tab value can be resolved; keep each JSDoc short (one-two sentences) and include prop highlights where helpful.Source: Coding guidelines
49-52: 💤 Low valueSilent return on invalid tab change could be confusing.
When
itemsis provided andnextValueis not in the list, the handler silently returns without updating state or providing feedback. Consider adding a development-time warning to help debug issues.💡 Optional enhancement
onValueChange={(nextValue) => { if (items && !items.includes(nextValue)) { + console.warn(`Tab value "${nextValue}" is not in the items list:`, items); return; } setValue(nextValue); }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/mdx-tabs.tsx` around lines 49 - 52, The onValueChange handler in mdx-tabs.tsx currently silently returns if items is set and nextValue isn't included; update the handler (the onValueChange callback that checks items, nextValue, and calls setValue) to emit a development-time warning when this occurs (e.g., guard with NODE_ENV !== 'production' or a dev-only logger) so developers see why the state wasn't updated, then still return without changing state; keep the existing items/includes/ setValue logic but add a clear message referencing nextValue and the items list.apps/web/src/components/docs/docs-mdx-components.tsx (1)
262-298: ⚡ Quick winAdd JSDoc to the exported docsMdxComponents.
This constant forms the public API for MDX component overrides and would benefit from documentation. As per coding guidelines, JSDoc should be added on APIs used in many places or user-facing.
📝 Suggested JSDoc
/** * MDX component overrides for documentation pages. * Maps standard HTML/MDX elements to styled React components. * Includes custom components like Callout, Card, Steps, and Tabs. */ export const docsMdxComponents = { // ... } satisfies MDXComponents;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/docs/docs-mdx-components.tsx` around lines 262 - 298, Add a brief JSDoc block immediately above the export const docsMdxComponents declaration that describes this symbol as the MDX component overrides used by documentation pages: state that it maps standard HTML/MDX elements (e.g., h1..h6, p, a, code, ul/ol/li, table, etc.) to styled React components and also exposes custom components like Callout, Card, Cards, Steps/Step/StepContent/StepTitle, Tabs/MdxTabs/MdxTab, Features, etc.; note that it satisfies the MDXComponents type and is a public API for MDX rendering. Keep the comment short and descriptive per coding guidelines.Source: Coding guidelines
apps/web/content/docs/quickstart.mdx (1)
6-6: Docs links:/docs/*targets exist.The referenced MDX pages exist in
apps/web/content/docs:installation.mdx,plans-and-features.mdx,subscriptions.mdx, andentitlements.mdx, so the/docs/installation,/docs/plans-and-features,/docs/subscriptions, and/docs/entitlementslinks should resolve.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/content/docs/quickstart.mdx` at line 6, Update the doc links in apps/web/content/docs/quickstart.mdx so they point to the existing MDX pages: replace or verify the link text in the sentence "This page assumes you have completed the [installation](/docs/installation) steps..." and any other references to docs with the exact route slugs that exist (/docs/installation, /docs/plans-and-features, /docs/subscriptions, /docs/entitlements) to ensure they resolve to installation.mdx, plans-and-features.mdx, subscriptions.mdx, and entitlements.mdx respectively.apps/web/src/components/sections/feedback-section.tsx (1)
78-78: ⚡ Quick winUse
tweet.linkas the key for better uniqueness.The current key
${tweet.handle}-${tweet.text}could collide if the same user posts similar text. Since each tweet has a uniquelinkfield, usingtweet.linkas the key would be more robust and align with React best practices.♻️ Proposed fix
- <TweetCard key={`${tweet.handle}-${tweet.text}`} tweet={tweet} /> + <TweetCard key={tweet.link} tweet={tweet} />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/sections/feedback-section.tsx` at line 78, Replace the current fragile list key generation for TweetCard with the tweet's unique link: locate where TweetCard is rendered (the TweetCard component usage in feedback-section.tsx) and change the key from the template `${tweet.handle}-${tweet.text}` to use `tweet.link` so each rendered TweetCard uses the stable unique identifier `tweet.link` as the React key.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@AGENTS.md`:
- Around line 26-30: Fix typos and tighten the sentence in AGENTS.md: replace
"clonned" with "cloned", capitalize the sentence start after the comma, and
rephrase the guidance to read clearly (e.g., "If you need to inspect source code
of libraries or packages, prefer inspecting the cloned source repository when
available, rather than the library dist. These directories already contain
source checkouts for some packages: `~/ref/fumadocs` - fumadocs framework /
package."). Update the sentence containing "clonned" and the following line
referencing `~/ref/fumadocs`.
In `@apps/web/src/app/`(marketing)/page.tsx:
- Line 3: The codebase now renders FeedbackSection while FeaturesSection has no
remaining references; confirm whether FeaturesSection (the component defined as
FeaturesSection in features-section.tsx) is intentionally retired—if yes, delete
the FeaturesSection component file or mark it deprecated/moved and remove its
export; if it's still needed, rewire the page to import and render
FeaturesSection where appropriate (replace or combine with FeedbackSection) and
update any exports/imports so FeaturesSection is actually referenced.
In `@apps/web/src/components/docs/docs-mdx-components.tsx`:
- Around line 56-58: The heading ID generation in getHeadingId can produce
collisions (e.g., "What's new?" and "Whats new" both become "whats-new"); fix by
switching to a robust slugger or adding collision detection: import and use a
slug library like GithubSlugger and call slugger.slug(children?.toString() ??
'') inside getHeadingId, or maintain a module-level Set (e.g., usedIds) and,
after creating the base slug from children, append a numeric suffix while
usedIds.has(id) to ensure uniqueness, then add the final id to usedIds before
returning; update getHeadingId to use one of these approaches.
---
Nitpick comments:
In `@apps/web/content/docs/quickstart.mdx`:
- Line 6: Update the doc links in apps/web/content/docs/quickstart.mdx so they
point to the existing MDX pages: replace or verify the link text in the sentence
"This page assumes you have completed the [installation](/docs/installation)
steps..." and any other references to docs with the exact route slugs that exist
(/docs/installation, /docs/plans-and-features, /docs/subscriptions,
/docs/entitlements) to ensure they resolve to installation.mdx,
plans-and-features.mdx, subscriptions.mdx, and entitlements.mdx respectively.
In `@apps/web/src/components/docs/docs-code-surface.tsx`:
- Around line 5-16: Add a JSDoc block above the exported DocsCodeSurface
function that documents the component's purpose (renders a styled <pre> wrapper
for code blocks in the docs system), lists its props (including className,
tabIndex, and other ComponentProps<"pre"> passed via ...props), and explicitly
states the default tabIndex behavior (defaults to 0 when tabIndex is undefined).
Mention any accessibility notes (keyboard focusability due to tabIndex) and the
fact that it spreads remaining pre props onto the element; reference the
DocsCodeSurface function name so the comment is colocated with the
implementation.
In `@apps/web/src/components/docs/docs-mdx-components.tsx`:
- Around line 262-298: Add a brief JSDoc block immediately above the export
const docsMdxComponents declaration that describes this symbol as the MDX
component overrides used by documentation pages: state that it maps standard
HTML/MDX elements (e.g., h1..h6, p, a, code, ul/ol/li, table, etc.) to styled
React components and also exposes custom components like Callout, Card, Cards,
Steps/Step/StepContent/StepTitle, Tabs/MdxTabs/MdxTab, Features, etc.; note that
it satisfies the MDXComponents type and is a public API for MDX rendering. Keep
the comment short and descriptive per coding guidelines.
In `@apps/web/src/components/docs/mdx-tabs.tsx`:
- Around line 32-68: Add concise JSDoc comments to each exported MDX tabs
component to document their purpose and key props: add a brief description above
MdxTabs explaining it's the root tabs component and noting controlled selection
props (items, defaultIndex/defaultValue, label), add a short comment above
MdxTabsList describing it as the tab list container with indicator, above
MdxTabsTab describing it as the individual tab trigger and key props (value,
children), above MdxTabsPanel describing it as the content panel, and above
MdxTab describing it as a convenience wrapper that resolves value from props or
context and include a `@throws` note stating it throws if no tab value can be
resolved; keep each JSDoc short (one-two sentences) and include prop highlights
where helpful.
- Around line 49-52: The onValueChange handler in mdx-tabs.tsx currently
silently returns if items is set and nextValue isn't included; update the
handler (the onValueChange callback that checks items, nextValue, and calls
setValue) to emit a development-time warning when this occurs (e.g., guard with
NODE_ENV !== 'production' or a dev-only logger) so developers see why the state
wasn't updated, then still return without changing state; keep the existing
items/includes/ setValue logic but add a clear message referencing nextValue and
the items list.
In `@apps/web/src/components/docs/package-command-pre.tsx`:
- Around line 60-85: Add a JSDoc block to the exported async component
PackageCommandPre describing its behavior and purpose: explain that it
normalizes and parses text via normalizeCommand and extractText, conditionally
parses with parsePackageCommand, checks language with isShellLanguage, generates
highlighted entries by mapping packageManagers and calling highlightShellCommand
and commandForManager, and renders either PackageManagerCommandBlock with
highlightedCommands or DefaultPre; include param description for props
(ComponentProps<"pre"> & { "data-language"?: string }), the return type
(JSX.Element | Promise<JSX.Element>), and note that it performs async
highlighting side-effects.
In `@apps/web/src/components/docs/package-command-utils.ts`:
- Around line 5-24: Add JSDoc comments for the exported PackageCommand interface
and the commandForManager function: document PackageCommand purpose and fields
(kind: CommandKind and args: string), and for commandForManager describe
purpose, parameters (command: PackageCommand, manager: PackageManager), behavior
for each CommandKind branch (how npm/yarn/pnpm/bun are mapped), and the return
value (string command). Ensure the JSDoc is placed immediately above the
exported declarations and mentions any edge cases (e.g., defaulting to pnpm for
dlx) so consumers understand the public API.
In `@apps/web/src/components/docs/package-command.tsx`:
- Around line 35-50: The code currently persists package manager selections to
both sessionStorage and localStorage in setStoredManager and reads from both in
readStoredManager; decide on a single storage medium (prefer localStorage for
cross-tab persistence) and simplify by writing only to localStorage and reading
only from localStorage using packageManagerStorageKey, leaving
packageManagerListeners and isPackageManager logic unchanged; if session-scoped
behavior is required, document the intent or add a separate explicit function,
otherwise remove sessionStorage calls to avoid redundant writes and confusing
read fallback behavior.
- Around line 176-182: Extract the duplicated extractText function into a single
shared utility: create a new utils module that exports extractText, import
isValidElement from "react" and keep the same implementation/typing, then
replace the local copies in the package-command and package-command-pre
components with an import from the new utility and delete the duplicate
definitions.
In `@apps/web/src/components/docs/package-manager-state.ts`:
- Around line 1-21: Add JSDoc comments to document the module's public API:
describe the exported PackageManager type (allowed values), the packageManagers
array (list of supported managers), packageManagerStorageKey (purpose/key used
in storage), and fallbackPackageManager (default). For functions
isPackageManager(value) and parsePackageManager(value) add JSDoc describing
parameters and return types/guards (e.g., `@param` value - input
string|null/undefined; `@returns` boolean for isPackageManager and PackageManager
for parsePackageManager), and a short usage example or note about behavior
(parse returns fallback when invalid). Place comments immediately above each
exported symbol (PackageManager, packageManagers, packageManagerStorageKey,
fallbackPackageManager, isPackageManager, parsePackageManager).
In `@apps/web/src/components/layout/navigation-bar.tsx`:
- Line 51: Remove the unnecessary separator comment line ("// ─── Data
────────────────────────────────────────────────────────────") from the
NavigationBar component in apps/web/src/components/layout/navigation-bar.tsx;
locate the comment near the top of the file (around where module-level
data/constants are defined) and delete that single-line separator so the file
follows the project's guideline of avoiding separator comments.
- Line 86: Remove the unnecessary separator comment "// ─── Tab styles
──────────────────────────────────────────────────────" from the NavigationBar
component in apps/web/src/components/layout/navigation-bar.tsx; simply delete
that standalone comment line (no code changes otherwise) to comply with the
guideline of avoiding separator comments in TypeScript/JavaScript files.
- Line 15: Remove the unnecessary separator comment line "// ─── Shared nav link
─────────────────────────────────────────────────" from the navigation-bar
component; locate the comment above the shared nav link code (around the
SharedNavLink / NavLink related JSX or function) and delete the separator so
only meaningful comments or code remain, following the project's guideline to
avoid decorative separator comments.
- Line 96: Remove the unnecessary separator comment line ("// ─── Component
───────────────────────────────────────────────────────") from the NavigationBar
component file; locate it in the navigation-bar.tsx near the component
declaration and delete that single comment so the file follows the guideline of
avoiding visual separator comments.
- Line 98: The NavigationBar component currently accepts an unused parameter
named _stars and renders a hardcoded "1k"; either remove the unused prop or
surface and use the actual value: change the parameter from { stars: _stars } to
{ stars } (or remove it altogether) in the NavigationBar function, replace the
hardcoded "1k" in the GitHub button render with a dynamic display like stars ??
"1k" (or remove the stars display if you choose to drop the prop), and update
any callers that pass null to NavigationBar to either stop passing the prop or
pass the real star count; also apply the same fix to the other duplicate
instance(s) of the NavigationBar prop usage.
In `@apps/web/src/components/sections/feedback-section.tsx`:
- Line 78: Replace the current fragile list key generation for TweetCard with
the tweet's unique link: locate where TweetCard is rendered (the TweetCard
component usage in feedback-section.tsx) and change the key from the template
`${tweet.handle}-${tweet.text}` to use `tweet.link` so each rendered TweetCard
uses the stable unique identifier `tweet.link` as the React key.
In `@apps/web/src/styles/globals.css`:
- Around line 286-288: There is a stylelint warning because there is no blank
line between the `@apply` rule and the subsequent declaration; update the block
containing the declarations "`@apply` overflow-x-hidden overflow-y-scroll;" and
"max-width: 100vw;" by inserting a single empty line before the "max-width:
100vw;" declaration so the `@apply` and the following property are separated per
stylelint rules.
- Line 96: The CSS custom property --secondary currently uses a hex value
(`#f5f5f5`) which is inconsistent with the rest of the theme that uses oklch();
update the --secondary declaration in globals.css to an equivalent oklch(...)
color so it matches the site's color space and tone (convert the hex to oklch
and replace the value for --secondary).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 48260000-d479-462e-958f-a01c96a8bad9
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (115)
AGENTS.mdapps/web/content/docs/cli.mdxapps/web/content/docs/client.mdxapps/web/content/docs/concepts/meta.jsonapps/web/content/docs/concepts/payment-providers.mdxapps/web/content/docs/customers.mdxapps/web/content/docs/dashboard.mdxapps/web/content/docs/database.mdxapps/web/content/docs/entitlements.mdxapps/web/content/docs/flows/meta.jsonapps/web/content/docs/get-started/meta.jsonapps/web/content/docs/guides/meta.jsonapps/web/content/docs/installation.mdxapps/web/content/docs/introduction.mdxapps/web/content/docs/meta.jsonapps/web/content/docs/metered-usage.mdxapps/web/content/docs/plans-and-features.mdxapps/web/content/docs/plugins.mdxapps/web/content/docs/plugins/meta.jsonapps/web/content/docs/providers/meta.jsonapps/web/content/docs/providers/stripe.mdxapps/web/content/docs/quickstart.mdxapps/web/content/docs/skills.mdxapps/web/content/docs/subscription-billing.mdxapps/web/content/docs/subscriptions.mdxapps/web/content/docs/typescript.mdxapps/web/content/docs/webhook-events.mdxapps/web/content/drafts/docs-index.mdxapps/web/mdx-components.tsxapps/web/next.config.jsapps/web/package.jsonapps/web/source.config.tsapps/web/src/app/(marketing)/blog/page.tsxapps/web/src/app/(marketing)/contact/contact-form.tsxapps/web/src/app/(marketing)/donate/page.tsxapps/web/src/app/(marketing)/layout.tsxapps/web/src/app/(marketing)/page.tsxapps/web/src/app/(marketing)/sponsor/page.tsxapps/web/src/app/api/og/[[...slug]]/route.tsxapps/web/src/app/docs/[[...slug]]/page.tsxapps/web/src/app/docs/layout.tsxapps/web/src/app/llms.txt/route.tsapps/web/src/app/not-found.tsxapps/web/src/components/command-menu.tsxapps/web/src/components/docs/copy-markdown-button.tsxapps/web/src/components/docs/docs-code-surface.tsxapps/web/src/components/docs/docs-icons.tsxapps/web/src/components/docs/docs-layout.tsxapps/web/src/components/docs/docs-mdx-components.tsxapps/web/src/components/docs/docs-page.tsxapps/web/src/components/docs/features.tsxapps/web/src/components/docs/mdx-tabs.tsxapps/web/src/components/docs/mdx-text.tsxapps/web/src/components/docs/package-command-pre.tsxapps/web/src/components/docs/package-command-utils.tsapps/web/src/components/docs/package-command.tsxapps/web/src/components/docs/package-manager-state.tsapps/web/src/components/docs/sidebar-category-accordion.tsxapps/web/src/components/docs/sidebar-collapse-button.tsxapps/web/src/components/docs/toc-footer.tsxapps/web/src/components/icons/index.tsxapps/web/src/components/layout/mini-nav-bar.tsxapps/web/src/components/layout/navigation-bar.tsxapps/web/src/components/layout/section.tsxapps/web/src/components/providers.tsxapps/web/src/components/sections/cta-section.tsxapps/web/src/components/sections/demo/demo-app-window.tsxapps/web/src/components/sections/demo/demo-backend-panel.tsxapps/web/src/components/sections/demo/demo-types.tsxapps/web/src/components/sections/demo/index.tsxapps/web/src/components/sections/features-section.tsxapps/web/src/components/sections/feedback-content.tsapps/web/src/components/sections/feedback-section.tsxapps/web/src/components/sections/footer-section.tsxapps/web/src/components/sections/hero-section.tsxapps/web/src/components/sections/readme-code-content.tsapps/web/src/components/sections/testimonials-section.tsxapps/web/src/components/sidebar-content.tsxapps/web/src/components/theme-switcher.tsxapps/web/src/components/ui/accordion.tsxapps/web/src/components/ui/breadcrumb.tsxapps/web/src/components/ui/button-group.tsxapps/web/src/components/ui/button.tsxapps/web/src/components/ui/calendar.tsxapps/web/src/components/ui/carousel.tsxapps/web/src/components/ui/checkbox.tsxapps/web/src/components/ui/code-block-content.tsxapps/web/src/components/ui/code-block.tsxapps/web/src/components/ui/combobox.tsxapps/web/src/components/ui/command.tsxapps/web/src/components/ui/context-menu.tsxapps/web/src/components/ui/dialog.tsxapps/web/src/components/ui/dropdown-menu.tsxapps/web/src/components/ui/dynamic-code-block.tsxapps/web/src/components/ui/frame-corners.tsxapps/web/src/components/ui/input-otp.tsxapps/web/src/components/ui/menubar.tsxapps/web/src/components/ui/native-select.tsxapps/web/src/components/ui/navigation-menu.tsxapps/web/src/components/ui/pagination.tsxapps/web/src/components/ui/select.tsxapps/web/src/components/ui/sheet.tsxapps/web/src/components/ui/sidebar.tsxapps/web/src/components/ui/sonner.tsxapps/web/src/components/ui/spinner.tsxapps/web/src/components/web/brand-menu.tsxapps/web/src/components/web/footer.tsxapps/web/src/components/web/hero-code-block.tsxapps/web/src/components/web/hero-title.tsxapps/web/src/lib/consts.tsapps/web/src/lib/lucide-react-remix-shim.tsapps/web/src/lib/shiki-themes.tsapps/web/src/lib/shiki-themes/shiki-aura-theme.tsapps/web/src/styles/globals.cssdev/DESIGN.md
💤 Files with no reviewable changes (15)
- apps/web/content/docs/concepts/meta.json
- apps/web/content/docs/concepts/payment-providers.mdx
- apps/web/content/docs/providers/stripe.mdx
- apps/web/src/components/docs/sidebar-collapse-button.tsx
- apps/web/content/docs/introduction.mdx
- apps/web/content/docs/providers/meta.json
- apps/web/content/docs/plugins/meta.json
- apps/web/src/app/(marketing)/donate/page.tsx
- apps/web/content/docs/guides/meta.json
- apps/web/src/components/sections/testimonials-section.tsx
- apps/web/content/docs/flows/meta.json
- apps/web/content/docs/get-started/meta.json
- apps/web/src/components/command-menu.tsx
- apps/web/src/components/docs/sidebar-category-accordion.tsx
- apps/web/src/lib/consts.ts
| If need to inspect source code of libraries or packages, prefer inspected clonned source repo while exists, instead of inspecting library dist. | ||
|
|
||
| those directories already contain the source checkout of some packages: | ||
|
|
||
| - `~/ref/fumadocs` - fumadocs framework / package. |
There was a problem hiding this comment.
Fix wording/typos in the new references guidance.
The new guidance has grammar/typo issues (clonned, lowercase sentence start) that make the rule harder to parse quickly. Tightening the wording will avoid ambiguity.
Suggested edit
-If need to inspect source code of libraries or packages, prefer inspected clonned source repo while exists, instead of inspecting library dist.
-
-those directories already contain the source checkout of some packages:
+If you need to inspect source code of libraries or packages, prefer an inspected cloned source repository (when available) instead of library dist artifacts.
+
+These directories already contain source checkouts of some packages:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| If need to inspect source code of libraries or packages, prefer inspected clonned source repo while exists, instead of inspecting library dist. | |
| those directories already contain the source checkout of some packages: | |
| - `~/ref/fumadocs` - fumadocs framework / package. | |
| If you need to inspect source code of libraries or packages, prefer an inspected cloned source repository (when available) instead of library dist artifacts. | |
| These directories already contain source checkouts of some packages: | |
| - `~/ref/fumadocs` - fumadocs framework / package. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@AGENTS.md` around lines 26 - 30, Fix typos and tighten the sentence in
AGENTS.md: replace "clonned" with "cloned", capitalize the sentence start after
the comma, and rephrase the guidance to read clearly (e.g., "If you need to
inspect source code of libraries or packages, prefer inspecting the cloned
source repository when available, rather than the library dist. These
directories already contain source checkouts for some packages: `~/ref/fumadocs`
- fumadocs framework / package."). Update the sentence containing "clonned" and
the following line referencing `~/ref/fumadocs`.
| import { CTASection } from "@/components/sections/cta-section"; | ||
| import { DemoSection } from "@/components/sections/demo"; | ||
| import { FeaturesSection } from "@/components/sections/features-section"; | ||
| import { FeedbackSection } from "@/components/sections/feedback-section"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify FeaturesSection usage and confirm it's intentionally removed
# Check for FeaturesSection imports or references
rg "FeaturesSection" apps/web/src -g '*.{ts,tsx}'
# Look for the FeaturesSection component file
fd FeaturesSection apps/web/src
# Check if FeedbackSection exists and is properly implemented
fd FeedbackSection apps/web/srcRepository: getpaykit/paykit
Length of output: 150
Confirm the FeaturesSection component is intentionally retired (and remove it if unused).
apps/web/src/app/(marketing)/page.tsxnow imports/rendersFeedbackSection.FeaturesSectionhas no remaining references underapps/web/src—it only exists as the definition inapps/web/src/components/sections/features-section.tsx.
IfFeaturesSectionis intentionally removed, delete it or mark it deprecated/moved; otherwise rewire it where it’s supposed to be used.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/app/`(marketing)/page.tsx at line 3, The codebase now renders
FeedbackSection while FeaturesSection has no remaining references; confirm
whether FeaturesSection (the component defined as FeaturesSection in
features-section.tsx) is intentionally retired—if yes, delete the
FeaturesSection component file or mark it deprecated/moved and remove its
export; if it's still needed, rewire the page to import and render
FeaturesSection where appropriate (replace or combine with FeedbackSection) and
update any exports/imports so FeaturesSection is actually referenced.
| function getHeadingId(children: ComponentPropsWithoutRef<"h2">["children"]) { | ||
| return children?.toString().replace(/ /g, "-").replace(/'/g, "").replace(/\?/g, "").toLowerCase(); | ||
| } |
There was a problem hiding this comment.
Heading ID generation could produce collisions.
The getHeadingId function uses simple string replacement that may produce duplicate IDs for different headings. For example, "What's new?" and "Whats new" would both become whats-new. Consider using a more robust slug generation library or adding collision detection.
🔧 Suggested improvement
Consider using a library like github-slugger for robust, collision-free ID generation:
import GithubSlugger from 'github-slugger';
const slugger = new GithubSlugger();
function getHeadingId(children: ComponentPropsWithoutRef<"h2">["children"]) {
return slugger.slug(children?.toString() ?? '');
}Or implement collision detection:
const usedIds = new Set<string>();
function getHeadingId(children: ComponentPropsWithoutRef<"h2">["children"]) {
let id = children?.toString().replace(/ /g, "-").replace(/'/g, "").replace(/\?/g, "").toLowerCase();
let counter = 1;
let uniqueId = id;
while (usedIds.has(uniqueId)) {
uniqueId = `${id}-${counter++}`;
}
usedIds.add(uniqueId);
return uniqueId;
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/components/docs/docs-mdx-components.tsx` around lines 56 - 58,
The heading ID generation in getHeadingId can produce collisions (e.g., "What's
new?" and "Whats new" both become "whats-new"); fix by switching to a robust
slugger or adding collision detection: import and use a slug library like
GithubSlugger and call slugger.slug(children?.toString() ?? '') inside
getHeadingId, or maintain a module-level Set (e.g., usedIds) and, after creating
the base slug from children, append a numeric suffix while usedIds.has(id) to
ensure uniqueness, then add the final id to usedIds before returning; update
getHeadingId to use one of these approaches.
Summary
Testing
Summary by CodeRabbit
New Features
Documentation
UI/UX